package com.huaguoguo.cyg.aspect;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.TableInfoHelper;
import com.huaguoguo.cyg.annotation.SkipIfKeyExists;
import com.huaguoguo.cyg.entity.tl.dto.TlServerDTO;
import com.huaguoguo.cyg.utils.SpringContextHolder;
import jdk.nashorn.internal.ir.IfNode;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * 类说明： 数据库操作切面<br/>
 * author:huaguoguo
 * Date: 2020/2/6
 * Time: 16:39
 */
@Aspect
@Slf4j
@Component
public class DAOAspect {

    /**
     * 日志打印批量插入的数据数量
     *
     * @param point
     * @return
     * @throws Throwable
     */
    @Around("execution(public * com.huaguoguo.cyg.service.*.data.*.saveBatch(..))")
    public Object printInsertNum(ProceedingJoinPoint point) throws Throwable {
        Object proceed = point.proceed();
        Object[] args = point.getArgs();
        Collection collection = (Collection) Arrays.stream(point.getArgs())
                .filter(arg -> arg instanceof Collection)
                .findFirst().orElse(new ArrayList<>());
        log.info("本次插入{}条数据", collection.size());
        return proceed;
    }

    @Around("@annotation(com.huaguoguo.cyg.annotation.SkipIfKeyExists)")
    public Object skipIfKeyExists(ProceedingJoinPoint point) throws Throwable {
        String[] keys = ((MethodSignature) point.getSignature()).getMethod().getAnnotation(SkipIfKeyExists.class).keys();
        Object[] args = point.getArgs();
        Collection arg0 = (Collection) args[0];
        if (CollUtil.isEmpty(arg0)) {
            log.info("列表参数无数据");
            return true;
        }
        // 查全量的表信息
        // 获取查询的表信息 来自mybatis-plus
        Class<?> dtoClass = arg0.stream().findFirst().get().getClass();
        TableInfo tableInfo = TableInfoHelper.getTableInfo(dtoClass);
        // 获取 tableInfo 中的mapper的全类名，截取出beanName并获得mapper对象
        String[] split = StrUtil.split(tableInfo.getCurrentNamespace(), ".");
        String beanName = StrUtil.lowerFirst(split[split.length - 1]);
        BaseMapper mapper = SpringContextHolder.context.getBean(beanName, BaseMapper.class);
        // 查数据库
        QueryWrapper wrapper = new QueryWrapper();
        // 查询字段加工 key是驼峰命名的
        String[] columns = Arrays.stream(keys).map(StrUtil::toUnderlineCase).toArray(String[]::new);
        wrapper.select(columns);
        List list = mapper.selectList(wrapper);
        // 表中没有数据跳过校验
        if (CollUtil.isEmpty(list)) {
            return point.proceed();
        }
        // arg0只保留keys的参数列表
        Field[] fields = ReflectUtil.getFields(dtoClass);
        arg0 = (Collection) arg0.stream().map(o -> {
            Arrays.stream(fields).filter(field -> !Modifier.toString(field.getModifiers()).contains("final"))
                    .filter(field -> !Arrays.asList(keys).contains(field.getName()))
                    .forEach(field -> {
                        if (!Modifier.toString(field.getModifiers()).contains("final")) {
                            ReflectUtil.setFieldValue(o, field, null);
                        }
                    });
            return o;

        }).collect(Collectors.toList());
        arg0.removeIf(list::contains);
        args[0] = arg0;
        Object proceed = point.proceed(args);
        return proceed;
    }
}
